﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
using System.Security.Cryptography;

namespace Helpers
{

    public class XMLHelper
    {
        #region common

        public static string getInnerText(XmlElement pvXmlEle_Parent)
        {

            return "";

        }

        public static string getInnerText(XmlElement pvXmlEle_Parent, string pvNodeName)
        {
            return (pvXmlEle_Parent.GetElementsByTagName(pvNodeName).Count > 0) ? pvXmlEle_Parent.GetElementsByTagName(pvNodeName)[0].InnerText : "";
        }
        public static XmlElement getElement(XmlElement pvXmlEle_Parent, string pvNodeName)
        {
            return (pvXmlEle_Parent.GetElementsByTagName(pvNodeName).Count > 0) ? (XmlElement)pvXmlEle_Parent.GetElementsByTagName(pvNodeName)[0] : null;
        }
        public static XmlElement newElement(XmlDocument pvXmlDocContext, string pvNodeName, string pvInnerText)
        {
            XmlElement _xmlEle = pvXmlDocContext.CreateElement(pvNodeName);
            _xmlEle.InnerText = pvInnerText;
            return _xmlEle;
        }
        public static XmlElement newElement(XmlDocument pvXmlDocContext, string pvNodeName)
        {
            return pvXmlDocContext.CreateElement(pvNodeName);
        }
        public static XmlAttribute newAttribute(XmlDocument pvXmlDoc, string pvKey, string pvValue)
        {
            XmlAttribute _xmlAttr = pvXmlDoc.CreateAttribute(pvKey);
            _xmlAttr.Value = pvValue;
            return _xmlAttr;
        }
        /// <summary>
        /// Encrypts the specified pv data string.
        /// </summary>
        /// <param name="pvDataString">The pv data string.</param>
        /// <returns></returns>
        public static string Encrypt(string pvDataString)
        {

            return BitConverter.ToString(new MD5CryptoServiceProvider().ComputeHash(new UTF8Encoding().GetBytes(pvDataString))).
                   ToLower().Replace("-", "");

        }

        public static string Encrypt(string key, string data)
        {
            data = data.Trim();

            byte[] keydata = Encoding.ASCII.GetBytes(key);

            string md5String = BitConverter.ToString(new MD5CryptoServiceProvider().ComputeHash(keydata)).Replace("-", "").ToLower();

            byte[] tripleDesKey = Encoding.ASCII.GetBytes(md5String.Substring(0, 24));

            TripleDES tripdes = TripleDES.Create();

            tripdes.Mode = CipherMode.ECB;

            tripdes.Key = tripleDesKey;

            tripdes.GenerateIV();

            var ms = new MemoryStream();

            var encStream = new CryptoStream(ms, tripdes.CreateEncryptor(), CryptoStreamMode.Write);

            encStream.Write(Encoding.ASCII.GetBytes(data), 0, Encoding.ASCII.GetByteCount(data));

            encStream.FlushFinalBlock();

            byte[] cryptoByte = ms.ToArray();

            ms.Close();

            encStream.Close();

            return Convert.ToBase64String(cryptoByte, 0, cryptoByte.GetLength(0)).Trim();
        }

        /// <summary>
        /// Decrypts the specified key.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="data">The data.</param>
        /// <returns></returns>
        public static string Decrypt(string key, string data)
        {
            byte[] keydata = Encoding.ASCII.GetBytes(key);

            string md5String = BitConverter.ToString(new
                                                         MD5CryptoServiceProvider().ComputeHash(keydata)).Replace("-",
                                                                                                                  "").
                Replace(" ", "+").ToLower();

            byte[] tripleDesKey = Encoding.ASCII.GetBytes(md5String.Substring(0, 24));

            TripleDES tripdes = TripleDES.Create();

            tripdes.Mode = CipherMode.ECB;

            tripdes.Key = tripleDesKey;

            byte[] cryptByte = Convert.FromBase64String(data);

            var ms = new MemoryStream(cryptByte, 0, cryptByte.Length);

            ICryptoTransform cryptoTransform = tripdes.CreateDecryptor();

            var decStream = new CryptoStream(ms, cryptoTransform,
                                             CryptoStreamMode.Read);

            var read = new StreamReader(decStream);

            return (read.ReadToEnd());
        }

        /// <summary>
        /// Decrypts the specified cipher string.
        /// </summary>
        /// <param name="cipherString">The cipher string.</param>
        /// <param name="useHashing">if set to <c>true</c> [use hashing].</param>
        /// <returns></returns>
        public static string Decrypt(string cipherString, bool useHashing)
        {
            byte[] keyArray;
            //get the byte code of the string

            byte[] toEncryptArray = Convert.FromBase64String(cipherString);

            System.Configuration.AppSettingsReader settingsReader =
                                                new AppSettingsReader();
            //Get your key from config file to open the lock!
            string key = (string)settingsReader.GetValue("SecurityKey",
                                                         typeof(String));

            if (useHashing)
            {
                //if hashing was used get the hash code with regards to your key
                MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
                keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
                //release any resource held by the MD5CryptoServiceProvider

                hashmd5.Clear();
            }
            else
            {
                //if hashing was not implemented get the byte code of the key
                keyArray = UTF8Encoding.UTF8.GetBytes(key);
            }

            TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
            //set the secret key for the tripleDES algorithm
            tdes.Key = keyArray;
            //mode of operation. there are other 4 modes. 
            //We choose ECB(Electronic code Book)

            tdes.Mode = CipherMode.ECB;
            //padding mode(if any extra byte added)
            tdes.Padding = PaddingMode.PKCS7;

            ICryptoTransform cTransform = tdes.CreateDecryptor();
            byte[] resultArray = cTransform.TransformFinalBlock(
                                 toEncryptArray, 0, toEncryptArray.Length);
            //Release resources held by TripleDes Encryptor                
            tdes.Clear();
            //return the Clear decrypted TEXT
            return UTF8Encoding.UTF8.GetString(resultArray);
        }

        #endregion common
    }
}
